package com.example.demo.information.service.impl;

import com.example.demo.account.entity.SecurityUser;
import com.example.demo.account.entity.SysUserRole;
import com.example.demo.common.utils.CommonUtil;
import com.example.demo.common.utils.Constant;
import com.example.demo.common.utils.ReadExcelUtils;
import com.example.demo.common.utils.SpringSecurityUtils;
import com.example.demo.information.entity.Bjxx;
import com.example.demo.information.entity.School;
import com.example.demo.information.entity.Student;
import com.example.demo.information.entity.info.StudentInfo;
import com.example.demo.information.repository.SchoolRepository;
import com.example.demo.information.repository.StudentRepository;
import com.example.demo.information.service.StudentService;
import com.google.common.collect.Lists;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.hssf.usermodel.*;
import org.apache.poi.hssf.util.HSSFColor;
import org.apache.poi.ss.usermodel.BorderStyle;
import org.apache.poi.ss.usermodel.HorizontalAlignment;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.io.BufferedOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.*;

@Service
@Transactional(rollbackFor = Exception.class)
public class StudentServiceImpl implements StudentService {

    @Autowired
    private StudentRepository studentRepository;

    @Override
    public List<Student> findAll() {return studentRepository.findAll();}

    @Override
    public List<Student> findNameLike(String name) {return studentRepository.findByNameLike(name);}

    @Override
    public List<Student> findBySfzOrXjfhOrNameLike(String searchVal) {
        return studentRepository.findBySfzOrXjfhOrNameLike(searchVal,searchVal,"%"+searchVal+"%");
    }

    @Override
    public Student findById(Long xsId) {
        return studentRepository.findById(xsId).get();
    }

    /**
     * 下载导入学生模板(固定字段类型)  通用
     * @param response
     */
    @Override
    public void createDownFile(HttpServletResponse response) {
        CommonUtil commonUtil = new CommonUtil();
        String uploadFileName = "班级学生信息导入模板"+ Constant.formatter2.get().format(new Date())+".xls";
        String sheetName = "学生信息";
        String[] excelTitleArr = new String[]{"学校名称","班级名称","姓名","身份证","学籍辅号","性别"};
        commonUtil.createExcelImpFile(uploadFileName,sheetName,excelTitleArr,response);
    }

    /**
     * 下载导入学生模板(固定字段类型)  学校管理员操作内容
     * @param response
     */
    @Override
    public void createDownFileStuExpForXXAdmin(HttpServletResponse response) {
        CommonUtil commonUtil = new CommonUtil();
        String uploadFileName = "班级学生信息导入模板"+ Constant.formatter2.get().format(new Date())+".xls";
        String sheetName = "学生信息";
        String[] excelTitleArr = new String[]{"班级名称","姓名","身份证","学籍辅号","性别"};
        commonUtil.createExcelImpFile(uploadFileName,sheetName,excelTitleArr,response);
    }

    /**
     * 从导入文件获取list
     * @param file
     * @param schoolMap
     * @param xxbjMap
     * @return
     */
    @Override
    public List<Student> getStuFromExpFile(MultipartFile file
            ,Map<String,School> schoolMap,Map<Long,Map<String ,Bjxx>> xxbjMap) throws Exception {

        List<Student> list = new ArrayList<>();
        ReadExcelUtils readBmFile = new ReadExcelUtils(file);
        /*
         * 表标题
         */
        String[] title = readBmFile.readExcelTitle();
        System.out.println(Arrays.toString(title));
        /*
         * 表内容,封装成list
         */
        Map<Integer, Map<Integer, Object>> content = readBmFile.readExcelContent();
        for(Map<Integer,Object> map:content.values()){
            Student student=new Student();
            if(StringUtils.isNotBlank((String)map.get(0))){//学校名称
                School school = schoolMap.get((String) map.get(0));
                if(school!=null){
                    student.setSchool(school);
                }else{
                    continue;
                }
            }else{
                continue;
            }
            if(StringUtils.isNotBlank((String)map.get(1))){//班级
                Bjxx bjxx = xxbjMap.get(student.getSchool().getId()).get((String) map.get(1));
                if(bjxx!=null){
                    student.setBjxx(bjxx);
                }else{
                    continue;
                }
            }else{
                continue;
            }
            if(StringUtils.isNotBlank((String)map.get(2))){//姓名
                student.setName((String)map.get(2));
            }else{
                continue;
            }
            if(StringUtils.isNotBlank((String)map.get(3))){//身份证
                student.setSfz((String)map.get(3));
            }else{
                continue;
            }
            if(StringUtils.isNotBlank((String)map.get(4))){//学籍辅号
                student.setXjfh((String)map.get(4));
            }else{
                continue;
            }
            if(StringUtils.isNotBlank((String)map.get(5))){//性别
                String sex = (String) map.get(5);
                sex = Constant.sexSet.contains(sex)?sex:"男";
                student.setSex(sex);
            }else{
                student.setSex("男");
            }
            list.add(student);
        }
        return list;
    }

    @Override
    public int saveList(List<Student> studentList) {
        int count = 0;
        for(Student student :studentList){
            //if(checkStudent(student)){
                studentRepository.save(student);
                count++;
            //}
        }
        return count;
    }

    /**
     * 检测学生的必须信息是否齐全(用于保存前)
     * @param student
     * @return
     */
    @Override
    public boolean checkStudent(Student student){
        boolean flag = false;
        if(StringUtils.isBlank(student.getSfz())
            ||StringUtils.isBlank(student.getXjfh())
            ||StringUtils.isBlank(student.getName())
            ||student.getBjxx()==null
            ||student.getBjxx().getId()==null
            ||student.getSchool()==null
            ||student.getSchool().getId()==null){
        }else{
            flag = true;
        }
        return flag;
    }

    @Override
    public List<Student> findBySfzOrXjfh(String sfz, String xjfh) {
        return studentRepository.findBySfzOrXjfh(sfz,xjfh);
    }

    @Override
    public void save(Student stu) {
        studentRepository.save(stu);
    }

    @Override
    public Student findBySfz(String sfz) {
        return studentRepository.findBySfz(sfz);
    }

    @Override
    public List<Student> findByBjId(String bjId) {
        return studentRepository.findByBjId(bjId);
    }

    /**
     * 获得学生列表
     * xxxxId!=null 查全校；bjxxId!=null 查全班；xsIds 查部分学生；
     * 从左到右先后判断
     * @param xxxxId
     * @param bjxxId
     * @param xsIds
     * @return
     */
    @Override
    public List<Student> getStuByXxxxIdBjxxIdXsIds(Long xxxxId, Long bjxxId, String xsIds) {
        List<Student> stuList = new ArrayList<>();
        if(xxxxId!=null){
            stuList = studentRepository.findByXxxxId(xxxxId);
        }else if(bjxxId!=null){
            stuList = studentRepository.findByBjxxId(bjxxId);
        }else{
            List<Long> xsIdList = new ArrayList<>();
            if(xsIds.lastIndexOf(",")!=-1){
                for(String s :xsIds.split(",")){
                    try {
                        Long xsIdL = Long.parseLong(s);
                        xsIdList.add(xsIdL);
                    } catch (NumberFormatException e) {
                        e.printStackTrace();
                        continue;
                    }
                }
            }else{
                xsIdList.add(Long.parseLong(xsIds));
            }
            stuList = studentRepository.findAllById(xsIdList);
        }
        return stuList;
    }

    /**
     *  查找学生(在id的范围下的学生list)
     * @param searchVal  搜索范围
     * @param id
     * @param type 用来判断id是谁的id  school bjxx ...
     * @return
     */
    @Override
    public List<Student> findByTypeAndSearch(String searchVal, Long id, String type) {
        List<Student> stuList;
        id = id!=null?id:-1;
        type = StringUtils.isNotBlank(type)?type:"null";
        if(StringUtils.isNotBlank(searchVal)){
            switch(type){
                case Constant.TreeTypeSchool:
                    stuList = studentRepository.findByXxxxIdAndSfzOrXjfhOrNameLike(id,searchVal,searchVal,"%"+searchVal+"%");
                    break;
                case Constant.TreeTypeBjxx:
                    stuList = studentRepository.findByBjxxIdAndSfzOrXjfhOrNameLike(id,searchVal,searchVal,"%"+searchVal+"%");
                    break;
                default:
                    stuList = studentRepository.findBySfzOrXjfhOrNameLike(searchVal,searchVal,"%"+searchVal+"%");
            }
        }else{
            switch(type){
                case Constant.TreeTypeSchool:
                    stuList = studentRepository.findByXxxxId(id);
                    break;
                case Constant.TreeTypeBjxx:
                    stuList = studentRepository.findByBjxxId(id);
                    break;
                default:
                    stuList = studentRepository.findAll();
            }
        }
        return stuList;
    }

    /**
     * 获取当前页的数据
     * @param stuInfoList
     * @param curr
     * @param limit
     * @return
     */
    @Override
    public List<StudentInfo> getCurrPageByStuInfoList(List<StudentInfo> stuInfoList, Integer curr, Integer limit) {
        int num = 0,count = 0;
        if(curr==null||limit==null){
            return stuInfoList;
        }
        int currNum = (curr-1)*limit;
        List<StudentInfo> list = new ArrayList<>();
        for(StudentInfo s :stuInfoList){
            if(num>=currNum&&count<limit){
                list.add(s);
                count++;
            }
            num++;
        }
        return list;
    }
    /**
     * 获取当前页的数据
     * @param stuList
     * @param curr
     * @param limit
     * @return
     */
    @Override
    public List<Student> getCurrPageByStuList(List<Student> stuList, Integer curr, Integer limit) {
        int num = 0,count = 0;
        if(curr==null||limit==null){
            return stuList;
        }
        int currNum = (curr-1)*limit;
        List<Student> list = new ArrayList<>();
        for(Student s :stuList){
            if(num>=currNum&&count<limit){
                list.add(s);
                count++;
            }
            num++;
        }
        return list;
    }

    /**
     * 根据当前的权限筛选下学生
     * @param studentList
     * @return
     */
    @Override
    public List<Student> findByRoleForStudentList(List<Student> studentList) {
        SecurityUser currentUserDetails = SpringSecurityUtils.getCurrentUserDetails();
        SysUserRole currSysUserRole = currentUserDetails.getCurrSysUserRole();
        Long xxxx_id=null;
        if(Constant.XX_USER_ID.equals(currSysUserRole.getRole_id())){
            if(currSysUserRole.getSchool_id()!=null){
                xxxx_id = currSysUserRole.getSchool_id();
            }else{
                return new ArrayList<>();
            }
        }
        if(xxxx_id==null){
            return studentList;
        }
        List<Student> list = new ArrayList<>();
        for(Student stu:studentList){
            if(xxxx_id.equals(stu.getSchool().getId())){
                list.add(stu);
            }
        }
        return list;
    }

    @Override
    public Map<String, Object> getStuAndBjxxFromExpFile(MultipartFile file, Map<String, School> schoolMap)
            throws Exception {
        SysUserRole currSysUserRole = SpringSecurityUtils.getCurrentUserDetails().getCurrSysUserRole();


        Map<String,Object> tabdataMap = new HashMap<>();
        List<Student> list = new ArrayList<>();
        List<String> bjmcList = new ArrayList<>();
        Map<Long,School> xxMap = new HashMap<>();
        Map<String,Object> paramMap = new HashMap<>();
        ReadExcelUtils readBmFile = new ReadExcelUtils(file);
        /*
         * 表标题
         */
        String[] title = readBmFile.readExcelTitle();
        System.out.println(Arrays.toString(title));
        /*
         * 表内容,封装成list
         */
        Map<Integer, Map<Integer, Object>> content = readBmFile.readExcelContent();
        int i=0;
        for(Map<Integer,Object> map:content.values()){
            Map<String,Object> tempMap = new HashMap<>();
            tempMap.put("num",String.valueOf(i));
            tabdataMap.put(String.valueOf(i++),tempMap);
            Student student=new Student();
            student.setErrMsg(String.valueOf(i-1));
            School school;
            int i0 = 0,i1 = 1,i2 = 2,i3 = 3,i4 = 4,i5 = 5;
            if(Constant.XX_USER_ID.equals(currSysUserRole.getRole_id())){
                i1 = 0;i2 = 1;i3 = 2;i4 = 3;i5 = 4;
            }
            tempMap.put("bjmc",(String)map.get(i1));
            tempMap.put("name",(String)map.get(i2));
            tempMap.put("sfz",(String)map.get(i3));
            tempMap.put("xjfh",(String)map.get(i4));
            tempMap.put("sex",(String)map.get(i5));
            if(!Constant.XX_USER_ID.equals(currSysUserRole.getRole_id())){
                tempMap.put("xxmc",(String) map.get(i0));
                if(StringUtils.isNotBlank((String)map.get(i0))){//学校名称
                    school = schoolMap.get((String) map.get(i0));
                    if(school!=null){
                        student.setSchool(school);
                        xxMap.put(school.getId(),school);
                    }else{
                        tempMap.put("errMsg","未匹配到学校");
                        continue;
                    }
                }else{
                    tempMap.put("errMsg","学校名称未填写");
                    continue;
                }
            }else{
                if(!schoolMap.values().iterator().hasNext()){
                    tempMap.put("errMsg","当前身份不是学校管理员或管理的学校不存在。");
                    continue;
                }else{
                    school = schoolMap.values().iterator().next();
                    if(school!=null){
                        student.setSchool(school);
                        xxMap.put(school.getId(),school);
                        tempMap.put("xxmc",school.getName());
                    }
                }
            }
            if(StringUtils.isNotBlank((String)map.get(i1))){//班级
                String xxbjmc = school.getId()+"@@"+(String)map.get(i1);
                bjmcList.add(xxbjmc);
                student.setXxbjmc((String)map.get(i1));
            }else{
                tempMap.put("errMsg","班级名称未填写");
                continue;
            }
            if(StringUtils.isNotBlank((String)map.get(i2))){//姓名
                student.setName((String)map.get(i2));
            }else{
                tempMap.put("errMsg","学生姓名未填写");
                continue;
            }
            if(StringUtils.isNotBlank((String)map.get(i3))){//身份证
                student.setSfz((String)map.get(i3));
            }else{
                tempMap.put("errMsg","学生身份证未填写");
                continue;
            }
            if(StringUtils.isNotBlank((String)map.get(i4))){//学籍辅号
                student.setXjfh((String)map.get(i4));
            }else{
                tempMap.put("errMsg","学生学籍辅号未填写");
                continue;
            }
            if(StringUtils.isNotBlank((String)map.get(i5))){//性别
                String sex = (String) map.get(i5);
                sex = Constant.sexSet.contains(sex)?sex:"男";
                student.setSex(sex);
            }else{
                student.setSex("男");
            }
            list.add(student);
        }
        paramMap.put("studentList",list);
        paramMap.put("bjmcList",bjmcList);
        paramMap.put("xxMap",xxMap);
        paramMap.put("tabdataMap",tabdataMap);
        return paramMap;
    }

    /**
     * 检测身份证或学籍辅号是否已存在。ture已存在，false不存在
     * @param sfz
     * @param xjfh
     * @return
     */
    @Override
    public boolean checkStudent(String sfz,String xjfh){
        List<Student> list = studentRepository.findBySfzOrXjfh(sfz,xjfh);
        return list!=null&&!list.isEmpty()?true:false;
    }

    /**
     * 页面上新增单个学生
     * @param studentInfo
     * @param school
     * @param bjxx
     * @return
     */
    @Override
    public String saveStuInfo(StudentInfo studentInfo,School school,Bjxx bjxx) {
        Student student = new Student(studentInfo);
        student.setBjxx(bjxx);
        student.setSchool(school);
        List<Student> list = studentRepository.findBySfzOrXjfh(student.getSfz(),student.getXjfh());
        if(list==null||list.isEmpty()){
            studentRepository.save(student);
            return "success";
        }else{
            return "存在身份证或学籍辅号相同学生。";
        }
    }

    /**
     * 普通新增,带检查下是否存在
     * @param student
     * @return
     */
    @Override
    public String saveStuAndCheck(Student student) {
        List<Student> list = studentRepository.findBySfzOrXjfh(student.getSfz(),student.getXjfh());
        if(list==null||list.isEmpty()){
            studentRepository.save(student);
            return "success";
        }else{
            return "存在身份证或学籍辅号相同学生。";
        }
    }

    @Override
    public void deleteById(Long xsId) {
        studentRepository.deleteById(xsId);
    }

}
